package io.gitee.thinkbungee.crud.mongo.controller;

import io.gitee.thinkbungee.bean.ResponseResult;
import io.gitee.thinkbungee.crud.BaseDTO;
import io.gitee.thinkbungee.crud.BaseEntity;
import io.gitee.thinkbungee.crud.PageParam;
import io.gitee.thinkbungee.crud.mongo.bean.MongoPage;
import io.gitee.thinkbungee.crud.mongo.service.SatelliteMongoBaseService;
import io.gitee.thinkbungee.utils.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * mongo 基础controller
 * <p>
 * 参考 @see SatelliteMybatisBaseController
 *
 * @author chenyichang
 * @date 2022/4/18
 */
public abstract class SatelliteMongoBaseController<P extends PageParam, T extends BaseEntity, D extends BaseDTO> {

    protected Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 获取service
     *
     * @return
     */
    public abstract SatelliteMongoBaseService<P, T> getService();

    /**
     * 获取当前controller的具体实体
     *
     * @return
     */
    public abstract T getEntity();

    /**
     * 获取当前controller的具体传输对象
     *
     * @return
     */
    public abstract D getDTO();


    //======================增删改查==========================//

    /**
     * 分页查询
     *
     * @param param 查询参数
     * @return
     */
    @GetMapping("/pageList")
    public ResponseResult pageList(P param) {
        MongoPage<T> mongoPage = getService().page(param);

        //需要把entity转换为DTO给前段
        List<T> records = mongoPage.getRecords();

        List<D> result = (List<D>) CollectionUtils.copyList(records, getDTO().getClass());

        //后置处理dto
        processAfterResult(result);


        MongoPage<D> page = new MongoPage<>();

        page.setCurrent(mongoPage.getCurrent());
        page.setRecords(result);
        page.setTotal(mongoPage.getTotal());
        page.setSize(mongoPage.getSize());

        return ResponseResult.success(page);
    }

    /**
     * 根据id查询记录
     *
     * @param id 主键id
     * @return
     */
    @GetMapping("/{id}")
    public ResponseResult detail(@PathVariable("id") String id) {
        T t = getService().selectById(id);
        D d = getDTO();
        BeanUtils.copyProperties(t, d);

        processAfterResult(d);

        return ResponseResult.success(d);
    }

    /**
     * 新增一条记录
     *
     * @param d 实体
     * @return
     */
    @PostMapping
    public ResponseResult insert(@Validated @RequestBody D d) {
        T t = getEntity();
        BeanUtils.copyProperties(d, t);
        getService().insert(t);
        return ResponseResult.success();
    }

    /**
     * 根据id修改记录
     *
     * @param d 实体
     * @return
     */
    @PutMapping
    public ResponseResult update(@Validated @RequestBody D d) {
        T t = getEntity();
        BeanUtils.copyProperties(d, t);
        getService().update(t);
        return ResponseResult.success();
    }


    /**
     * 根据id删除
     *
     * @param id 主键id
     * @return
     */
    @DeleteMapping("/{id}")
    public ResponseResult deleteById(@PathVariable("id") String id) {
        getService().deleteById(id);
        return ResponseResult.success();
    }

    /**
     * 根据ids批量删除
     *
     * @return
     */
    @PostMapping("/delete/batch")
    public ResponseResult deleteByBatchIds(@RequestBody List<String> ids) {
        getService().deleteByIds(ids);
        return ResponseResult.success(true);
    }


    /**
     * 对返回结果处理
     *
     * @param d 返回
     * @return
     */
    public D processAfterResult(D d) {
        return d;
    }


    /**
     * 对结果处理
     *
     * @param result
     */
    public List<D> processAfterResult(List<D> result) {
        return result;
    }


}
